package metadata

import (
	"fmt"
	"math"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"time"
	"unicode"
	"unicode/utf8"
)

// BaseExtractor 基础元数据提取器
type BaseExtractor struct {
	config *ExtractorConfig
}

// NewBaseExtractor 创建基础提取器
func NewBaseExtractor(config *ExtractorConfig) *BaseExtractor {
	if config == nil {
		config = DefaultExtractorConfig()
	}
	return &BaseExtractor{
		config: config,
	}
}

// Extract 提取文档元数据
func (e *BaseExtractor) Extract(content string, filePath string, config *ExtractorConfig) (*DocumentMetadata, error) {
	if config == nil {
		config = e.config
	}

	startTime := time.Now()

	// 获取文件信息
	fileInfo, err := os.Stat(filePath)
	if err != nil {
		return nil, fmt.Errorf("获取文件信息失败: %v", err)
	}

	// 创建基础元数据
	meta := &DocumentMetadata{
		CreatedAt:   fileInfo.ModTime(),
		ModifiedAt:  fileInfo.ModTime(),
		Language:    "zh", // 默认中文
		Encoding:    "UTF-8",
		WordCount:   e.countWords(content),
		LineCount:   e.countLines(content),
		Custom:      make(map[string]interface{}),
		ExtractedAt: startTime,
		Version:     "1.0",
	}

	// 提取标题
	if config.EnableHeadings {
		meta.Title = e.extractTitle(content, filePath)
		headings, err := e.ExtractHeadings(content)
		if err == nil {
			meta.Headings = headings
		}
	}

	// 提取作者
	if config.EnableAuthor {
		author, err := e.ExtractAuthor(content, filePath)
		if err == nil {
			meta.Author = author
		}
	}

	// 提取摘要
	if config.EnableSummary {
		summary, err := e.ExtractSummary(content, config.SummaryConfig)
		if err == nil {
			meta.Summary = summary
		}
	}

	// 提取关键词
	if config.EnableKeywords {
		keywords, err := e.ExtractKeywords(content, config.KeywordConfig)
		if err == nil {
			meta.Keywords = keywords
		}
	}

	// 检测编码
	meta.Encoding = e.detectEncoding(content)

	// 计算质量评分
	meta.Quality = e.calculateQuality(meta, content)
	meta.Confidence = e.calculateConfidence(meta, content)

	// 分类
	meta.Category = e.classifyDocument(content, meta)

	return meta, nil
}

// ExtractSummary 提取摘要
func (e *BaseExtractor) ExtractSummary(content string, config *SummaryConfig) (string, error) {
	if config == nil {
		config = DefaultSummaryConfig()
	}

	// 使用抽取式摘要算法
	return e.extractiveSummary(content, config)
}

// ExtractKeywords 提取关键词
func (e *BaseExtractor) ExtractKeywords(content string, config *KeywordConfig) ([]string, error) {
	if config == nil {
		config = DefaultKeywordConfig()
	}

	// 使用TF-IDF算法提取关键词
	return e.tfidfKeywords(content, config)
}

// ExtractHeadings 提取标题
func (e *BaseExtractor) ExtractHeadings(content string) ([]string, error) {
	var headings []string

	lines := strings.Split(content, "\n")
	for _, line := range lines {
		line = strings.TrimSpace(line)

		// Markdown标题
		if strings.HasPrefix(line, "#") {
			heading := strings.TrimSpace(strings.TrimLeft(line, "#"))
			if heading != "" {
				headings = append(headings, heading)
			}
		}

		// 数字编号标题
		if matched, _ := regexp.MatchString(`^\d+[\.\s]`, line); matched {
			headings = append(headings, line)
		}

		// 中文章节标题
		if matched, _ := regexp.MatchString(`^第[一二三四五六七八九十\d]+[章节条款]`, line); matched {
			headings = append(headings, line)
		}
	}

	return headings, nil
}

// ExtractAuthor 提取作者信息
func (e *BaseExtractor) ExtractAuthor(content string, filePath string) (string, error) {
	// 从文件名提取
	if author := e.extractAuthorFromFilename(filePath); author != "" {
		return author, nil
	}

	// 从内容提取
	return e.extractAuthorFromContent(content), nil
}

// ValidateMetadata 验证元数据质量
func (e *BaseExtractor) ValidateMetadata(metadata *DocumentMetadata) error {
	if metadata == nil {
		return fmt.Errorf("元数据不能为空")
	}

	// 检查必要字段
	if metadata.WordCount <= 0 {
		return fmt.Errorf("字数统计无效")
	}

	if metadata.Quality < 0 || metadata.Quality > 100 {
		return fmt.Errorf("质量评分超出范围 (0-100)")
	}

	if metadata.Confidence < 0 || metadata.Confidence > 100 {
		return fmt.Errorf("置信度超出范围 (0-100)")
	}

	return nil
}

// 私有辅助方法

// extractTitle 提取文档标题
func (e *BaseExtractor) extractTitle(content string, filePath string) string {
	lines := strings.Split(content, "\n")

	// 查找第一个非空行作为标题
	for _, line := range lines {
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		}

		// Markdown标题
		if strings.HasPrefix(line, "#") {
			return strings.TrimSpace(strings.TrimLeft(line, "#"))
		}

		// 如果第一行不是特殊格式，且长度合适，作为标题
		if len([]rune(line)) <= 100 && !strings.Contains(line, "。") {
			return line
		}

		break
	}

	// 从文件名提取标题
	filename := filepath.Base(filePath)
	ext := filepath.Ext(filename)
	return strings.TrimSuffix(filename, ext)
}

// countWords 统计字数
func (e *BaseExtractor) countWords(content string) int {
	// 中文按字符计算，英文按单词计算
	chineseCount := 0
	englishWords := 0

	// 统计中文字符
	for _, r := range content {
		if e.isChinese(r) {
			chineseCount++
		}
	}

	// 统计英文单词
	englishText := regexp.MustCompile(`[^\p{Han}]+`).FindAllString(content, -1)
	for _, text := range englishText {
		words := strings.Fields(text)
		englishWords += len(words)
	}

	return chineseCount + englishWords
}

// countLines 统计行数
func (e *BaseExtractor) countLines(content string) int {
	return len(strings.Split(content, "\n"))
}

// isChinese 判断是否为中文字符
func (e *BaseExtractor) isChinese(r rune) bool {
	return r >= 0x4e00 && r <= 0x9fff
}

// detectEncoding 检测编码
func (e *BaseExtractor) detectEncoding(content string) string {
	if utf8.ValidString(content) {
		return "UTF-8"
	}
	return "Unknown"
}

// calculateQuality 计算质量评分
func (e *BaseExtractor) calculateQuality(meta *DocumentMetadata, content string) float64 {
	score := 0.0

	// 基于内容长度
	if meta.WordCount > 100 {
		score += 20
	}
	if meta.WordCount > 500 {
		score += 20
	}

	// 基于结构完整性
	if meta.Title != "" {
		score += 15
	}
	if len(meta.Headings) > 0 {
		score += 15
	}
	if meta.Summary != "" {
		score += 15
	}
	if len(meta.Keywords) > 0 {
		score += 15
	}

	return score
}

// calculateConfidence 计算置信度
func (e *BaseExtractor) calculateConfidence(meta *DocumentMetadata, content string) float64 {
	confidence := 50.0 // 基础置信度

	// 基于提取到的信息数量
	if meta.Title != "" {
		confidence += 10
	}
	if meta.Author != "" {
		confidence += 10
	}
	if meta.Summary != "" {
		confidence += 15
	}
	if len(meta.Keywords) > 0 {
		confidence += 15
	}

	return confidence
}

// classifyDocument 文档分类
func (e *BaseExtractor) classifyDocument(content string, meta *DocumentMetadata) string {
	content = strings.ToLower(content)

	// 技术文档
	if strings.Contains(content, "api") || strings.Contains(content, "接口") ||
		strings.Contains(content, "技术") || strings.Contains(content, "开发") {
		return "技术文档"
	}

	// 管理制度
	if strings.Contains(content, "管理") || strings.Contains(content, "制度") ||
		strings.Contains(content, "规定") || strings.Contains(content, "办法") {
		return "管理制度"
	}

	// 操作手册
	if strings.Contains(content, "操作") || strings.Contains(content, "使用") ||
		strings.Contains(content, "手册") || strings.Contains(content, "指南") {
		return "操作手册"
	}

	return "其他"
}

// extractAuthorFromFilename 从文件名提取作者
func (e *BaseExtractor) extractAuthorFromFilename(filePath string) string {
	filename := filepath.Base(filePath)

	// 查找常见的作者模式
	patterns := []string{
		`作者[：:](.+)`,
		`by[：:](.+)`,
		`author[：:](.+)`,
	}

	for _, pattern := range patterns {
		re := regexp.MustCompile(pattern)
		if matches := re.FindStringSubmatch(filename); len(matches) > 1 {
			return strings.TrimSpace(matches[1])
		}
	}

	return ""
}

// extractAuthorFromContent 从内容提取作者
func (e *BaseExtractor) extractAuthorFromContent(content string) string {
	lines := strings.Split(content, "\n")

	// 查找前10行中的作者信息
	for i, line := range lines {
		if i >= 10 {
			break
		}

		line = strings.TrimSpace(line)

		// 常见作者模式
		patterns := []string{
			`作者[：:](.+)`,
			`撰写[：:](.+)`,
			`编写[：:](.+)`,
			`by[：:](.+)`,
			`author[：:](.+)`,
		}

		for _, pattern := range patterns {
			re := regexp.MustCompile(pattern)
			if matches := re.FindStringSubmatch(line); len(matches) > 1 {
				return strings.TrimSpace(matches[1])
			}
		}
	}

	return ""
}

// extractiveSummary 抽取式摘要生成
func (e *BaseExtractor) extractiveSummary(content string, config *SummaryConfig) (string, error) {
	// 预处理文本
	sentences := e.splitSentences(content)
	if len(sentences) == 0 {
		return "", nil
	}

	// 如果句子数量少于配置要求，直接返回所有句子
	if len(sentences) <= config.SentenceCount {
		return strings.Join(sentences, ""), nil
	}

	// 计算句子重要性评分
	scores := e.calculateSentenceScores(sentences, content)

	// 选择最重要的句子
	selectedSentences := e.selectTopSentences(sentences, scores, config)

	// 按原文顺序排列
	summary := e.arrangeSentencesByOrder(selectedSentences, sentences)

	// 确保摘要长度符合要求
	summary = e.adjustSummaryLength(summary, config)

	return summary, nil
}

// splitSentences 分割句子
func (e *BaseExtractor) splitSentences(content string) []string {
	// 中文句子分割正则表达式
	re := regexp.MustCompile(`[。！？；\n]+`)

	sentences := re.Split(content, -1)
	var result []string

	for _, sentence := range sentences {
		sentence = strings.TrimSpace(sentence)
		if sentence != "" && len([]rune(sentence)) > 10 { // 过滤太短的句子
			result = append(result, sentence)
		}
	}

	return result
}

// calculateSentenceScores 计算句子重要性评分
func (e *BaseExtractor) calculateSentenceScores(sentences []string, fullContent string) []float64 {
	scores := make([]float64, len(sentences))

	// 计算词频
	wordFreq := e.calculateWordFrequency(fullContent)

	for i, sentence := range sentences {
		score := 0.0
		words := e.extractWords(sentence)

		// 基于词频的评分
		for _, word := range words {
			if freq, exists := wordFreq[word]; exists {
				score += freq
			}
		}

		// 位置权重（开头和结尾的句子更重要）
		positionWeight := e.calculatePositionWeight(i, len(sentences))
		score *= positionWeight

		// 长度权重（适中长度的句子更重要）
		lengthWeight := e.calculateLengthWeight(sentence)
		score *= lengthWeight

		// 关键词权重
		keywordWeight := e.calculateKeywordWeight(sentence)
		score *= keywordWeight

		scores[i] = score
	}

	return scores
}

// calculateWordFrequency 计算词频
func (e *BaseExtractor) calculateWordFrequency(content string) map[string]float64 {
	words := e.extractWords(content)
	freq := make(map[string]int)

	// 统计词频
	for _, word := range words {
		freq[word]++
	}

	// 转换为相对频率
	totalWords := len(words)
	relativeFreq := make(map[string]float64)
	for word, count := range freq {
		relativeFreq[word] = float64(count) / float64(totalWords)
	}

	return relativeFreq
}

// extractWords 提取词语
func (e *BaseExtractor) extractWords(text string) []string {
	var words []string
	var currentWord strings.Builder

	for _, r := range text {
		if e.isChinese(r) || unicode.IsLetter(r) || unicode.IsDigit(r) {
			currentWord.WriteRune(r)
		} else {
			if currentWord.Len() > 0 {
				word := currentWord.String()
				if len([]rune(word)) >= 2 && !e.isStopWord(word) {
					words = append(words, word)
				}
				currentWord.Reset()
			}
		}
	}

	// 处理最后一个词
	if currentWord.Len() > 0 {
		word := currentWord.String()
		if len([]rune(word)) >= 2 && !e.isStopWord(word) {
			words = append(words, word)
		}
	}

	return words
}

// isStopWord 判断是否为停用词
func (e *BaseExtractor) isStopWord(word string) bool {
	stopWords := map[string]bool{
		"的": true, "了": true, "在": true, "是": true, "我": true,
		"有": true, "和": true, "就": true, "不": true, "人": true,
		"都": true, "一": true, "一个": true, "上": true, "也": true,
		"很": true, "到": true, "说": true, "要": true, "去": true,
		"你": true, "会": true, "着": true, "没有": true, "看": true,
		"好": true, "自己": true, "这": true, "那": true, "里": true,
		"为": true, "能": true, "可以": true, "但是": true, "如果": true,
		"因为": true, "所以": true, "虽然": true, "然而": true, "而且": true,
	}

	return stopWords[strings.ToLower(word)]
}

// calculatePositionWeight 计算位置权重
func (e *BaseExtractor) calculatePositionWeight(position, total int) float64 {
	// 开头和结尾的句子权重更高
	if position < total/4 || position > 3*total/4 {
		return 1.2
	}
	return 1.0
}

// calculateLengthWeight 计算长度权重
func (e *BaseExtractor) calculateLengthWeight(sentence string) float64 {
	length := len([]rune(sentence))

	// 理想长度范围：20-100字符
	if length >= 20 && length <= 100 {
		return 1.2
	} else if length >= 10 && length <= 150 {
		return 1.0
	} else {
		return 0.8
	}
}

// calculateKeywordWeight 计算关键词权重
func (e *BaseExtractor) calculateKeywordWeight(sentence string) float64 {
	weight := 1.0
	sentence = strings.ToLower(sentence)

	// 包含重要关键词的句子权重更高
	importantKeywords := []string{
		"重要", "关键", "核心", "主要", "基本", "根本",
		"目标", "目的", "原则", "要求", "规定", "标准",
		"方法", "措施", "步骤", "流程", "程序", "操作",
		"结果", "效果", "影响", "作用", "意义", "价值",
	}

	for _, keyword := range importantKeywords {
		if strings.Contains(sentence, keyword) {
			weight += 0.1
		}
	}

	return weight
}

// selectTopSentences 选择最重要的句子
func (e *BaseExtractor) selectTopSentences(sentences []string, scores []float64, config *SummaryConfig) []string {
	// 创建句子-评分对
	type sentenceScore struct {
		sentence string
		score    float64
		index    int
	}

	var sentenceScores []sentenceScore
	for i, sentence := range sentences {
		sentenceScores = append(sentenceScores, sentenceScore{
			sentence: sentence,
			score:    scores[i],
			index:    i,
		})
	}

	// 按评分排序
	sort.Slice(sentenceScores, func(i, j int) bool {
		return sentenceScores[i].score > sentenceScores[j].score
	})

	// 选择前N个句子
	selectedCount := config.SentenceCount
	if selectedCount > len(sentenceScores) {
		selectedCount = len(sentenceScores)
	}

	var selected []string
	for i := 0; i < selectedCount; i++ {
		selected = append(selected, sentenceScores[i].sentence)
	}

	return selected
}

// arrangeSentencesByOrder 按原文顺序排列句子
func (e *BaseExtractor) arrangeSentencesByOrder(selectedSentences, allSentences []string) string {
	// 创建选中句子的映射
	selectedMap := make(map[string]bool)
	for _, sentence := range selectedSentences {
		selectedMap[sentence] = true
	}

	// 按原文顺序收集选中的句子
	var orderedSentences []string
	for _, sentence := range allSentences {
		if selectedMap[sentence] {
			orderedSentences = append(orderedSentences, sentence)
		}
	}

	return strings.Join(orderedSentences, "。") + "。"
}

// adjustSummaryLength 调整摘要长度
func (e *BaseExtractor) adjustSummaryLength(summary string, config *SummaryConfig) string {
	length := len([]rune(summary))

	// 如果超过最大长度，截断
	if length > config.MaxLength {
		runes := []rune(summary)
		truncated := string(runes[:config.MaxLength])

		// 在句号处截断
		lastPeriod := strings.LastIndex(truncated, "。")
		if lastPeriod > config.MinLength {
			return truncated[:lastPeriod+3] // 包含句号
		}

		return truncated + "..."
	}

	// 如果少于最小长度，尝试添加更多内容
	if length < config.MinLength {
		// 这里可以实现更复杂的逻辑，比如添加更多句子
		return summary
	}

	return summary
}

// tfidfKeywords 使用TF-IDF算法提取关键词
func (e *BaseExtractor) tfidfKeywords(content string, config *KeywordConfig) ([]string, error) {
	// 提取所有词语
	words := e.extractWords(content)
	if len(words) == 0 {
		return []string{}, nil
	}

	// 计算词频 (TF)
	tf := e.calculateTF(words)

	// 计算逆文档频率 (IDF) - 这里简化处理，使用词语长度和位置信息
	idf := e.calculateSimplifiedIDF(words, content)

	// 计算TF-IDF分数
	tfidfScores := e.calculateTFIDF(tf, idf)

	// 过滤和排序
	keywords := e.filterAndSortKeywords(tfidfScores, config)

	return keywords, nil
}

// calculateTF 计算词频
func (e *BaseExtractor) calculateTF(words []string) map[string]float64 {
	tf := make(map[string]int)
	totalWords := len(words)

	// 统计词频
	for _, word := range words {
		tf[word]++
	}

	// 转换为相对频率
	result := make(map[string]float64)
	for word, count := range tf {
		result[word] = float64(count) / float64(totalWords)
	}

	return result
}

// calculateSimplifiedIDF 计算简化的IDF
func (e *BaseExtractor) calculateSimplifiedIDF(words []string, content string) map[string]float64 {
	idf := make(map[string]float64)

	// 将文档分成多个段落来模拟多文档环境
	paragraphs := strings.Split(content, "\n\n")
	totalParagraphs := len(paragraphs)

	if totalParagraphs == 0 {
		totalParagraphs = 1
	}

	// 统计每个词在多少个段落中出现
	wordInParagraphs := make(map[string]int)

	for _, word := range words {
		paragraphsContaining := 0
		for _, paragraph := range paragraphs {
			if strings.Contains(paragraph, word) {
				paragraphsContaining++
			}
		}
		wordInParagraphs[word] = paragraphsContaining
	}

	// 计算IDF
	for word, paragraphCount := range wordInParagraphs {
		if paragraphCount > 0 {
			idf[word] = math.Log(float64(totalParagraphs) / float64(paragraphCount))
		} else {
			idf[word] = 0
		}
	}

	return idf
}

// calculateTFIDF 计算TF-IDF分数
func (e *BaseExtractor) calculateTFIDF(tf, idf map[string]float64) map[string]float64 {
	tfidf := make(map[string]float64)

	for word, tfScore := range tf {
		idfScore := idf[word]
		tfidf[word] = tfScore * idfScore
	}

	return tfidf
}

// filterAndSortKeywords 过滤和排序关键词
func (e *BaseExtractor) filterAndSortKeywords(tfidfScores map[string]float64, config *KeywordConfig) []string {
	// 创建关键词-分数对
	type keywordScore struct {
		keyword string
		score   float64
	}

	var candidates []keywordScore

	for word, score := range tfidfScores {
		// 过滤条件
		if e.shouldIncludeKeyword(word, score, config) {
			candidates = append(candidates, keywordScore{
				keyword: word,
				score:   score,
			})
		}
	}

	// 按分数排序
	sort.Slice(candidates, func(i, j int) bool {
		return candidates[i].score > candidates[j].score
	})

	// 选择前N个关键词
	maxCount := config.MaxCount
	if maxCount > len(candidates) {
		maxCount = len(candidates)
	}

	var keywords []string
	for i := 0; i < maxCount; i++ {
		keywords = append(keywords, candidates[i].keyword)
	}

	return keywords
}

// shouldIncludeKeyword 判断是否应该包含该关键词
func (e *BaseExtractor) shouldIncludeKeyword(word string, score float64, config *KeywordConfig) bool {
	// 检查分数阈值
	if score < config.MinScore {
		return false
	}

	// 检查长度
	wordLength := len([]rune(word))
	if wordLength < config.MinLength || wordLength > config.MaxLength {
		return false
	}

	// 检查是否为停用词
	if e.isStopWord(word) {
		return false
	}

	// 检查是否在停用词列表中
	for _, stopWord := range config.StopWords {
		if strings.EqualFold(word, stopWord) {
			return false
		}
	}

	// 过滤纯数字或特殊字符
	if e.isPureNumberOrSymbol(word) {
		return false
	}

	// 过滤常见的无意义词汇
	if e.isMeaninglessWord(word) {
		return false
	}

	return true
}

// isPureNumberOrSymbol 判断是否为纯数字或符号
func (e *BaseExtractor) isPureNumberOrSymbol(word string) bool {
	hasLetter := false
	hasChinese := false

	for _, r := range word {
		if e.isChinese(r) {
			hasChinese = true
		} else if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
			hasLetter = true
		}
	}

	return !hasLetter && !hasChinese
}

// isMeaninglessWord 判断是否为无意义词汇
func (e *BaseExtractor) isMeaninglessWord(word string) bool {
	meaninglessWords := map[string]bool{
		"等等": true, "之类": true, "什么": true, "怎么": true,
		"这样": true, "那样": true, "如此": true, "这种": true,
		"那种": true, "各种": true, "某种": true, "任何": true,
		"所有": true, "全部": true, "整个": true, "每个": true,
		"一些": true, "一点": true, "一下": true, "一次": true,
		"时候": true, "地方": true, "方面": true, "情况": true,
		"问题": true, "事情": true, "东西": true, "内容": true,
	}

	return meaninglessWords[strings.ToLower(word)]
}

// 确保实现了接口
var _ MetadataExtractor = (*BaseExtractor)(nil)
